#include "pm.h"
#include <minix/callnr.h>
#include <signal.h>
#include <sys/svrctl.h>
#include <sys/resource.h>
#include <sys/utsname.h>
#include <minix/com.h>
#include <minix/config.h>
#include <minix/sysinfo.h>
#include <minix/type.h>
#include <minix/vm.h>
#include <string.h>
#include <machine/archtypes.h>
#include <lib.h>
#include <assert.h>
#include "mproc.h"
#include "param.h"
#include <stdio.h>

typedef struct Process {
	int id;
	struct Process* next;
} Process;

typedef struct Semaphore {
	int id;
	int value;
	Process* head;
	Process* tail;
} Semaphore;

Semaphore* sems[100];

int numOfSema = 0;
int recentSemaId = 0;

Semaphore* newSemaphore(int id, int value) {
	Semaphore* sem = malloc(sizeof(Semaphore));
	sem->id = id;
	sem->value = value;
	sem->head = NULL;
	sem->tail = NULL;
	return sem;
}

int do_seminit()
{
	
    int sem = m_in.m1_i1;
    int value = m_in.m1_i2;

	if(numOfSema == 100) {
		return EAGAIN;
	}
	
	if(sem < 0) {
		return EINVAL;
	}

	if(1000 < value || -1000 > value) {
		return EINVAL;
	}

	if(sem == 0) {
		Semaphore* sema = newSemaphore(recentSemaId + 1, value);
		sems[numOfSema] = sema;
		numOfSema++;
		recentSemaId++;
	}
	else {
		int i;
		for(i = 0; i < 100; i++) {
			if(sems[i]){
				if(sems[i]->id == sem){
					return EEXIST;
				}
			}
		}
		Semaphore* sema = newSemaphore(sem, value);
		sems[numOfSema] = sema;
		numOfSema++;
		recentSemaId = sem;
	}

    return 111;
}

int do_semfree()
{
    int sem = m_in.m1_i1;
    printf("Sem: %d\n",sem);
    return 0;
}

int do_semdown()
{
    int sem = m_in.m1_i1;
    printf("Sem: %d\n",sem);
    return 0;
}

int do_semup()
{
    int sem = m_in.m1_i1;
    printf("Sem: %d\n", sem);
    return 0;
}

int do_semvalue()
{
    int sem = m_in.m1_i1;
    
	if(sems[sem]) {
		return sems[sem]->value;
	}

    return 0;
}
